home *** CD-ROM | disk | FTP | other *** search
/ Magnum One / Magnum One (Mid-American Digital) (Disc Manufacturing).iso / d21 / dvglue10.arc / DEMO.C < prev    next >
C/C++ Source or Header  |  1988-08-13  |  42KB  |  1,218 lines

  1. /*
  2. **      DEMO.C - DESQview API demonstration program.
  3. **      IBM Personal Computer - DESQview C Interface Demo.
  4. **    Written for Borland Turbo C v1.5.
  5. */
  6.  
  7. #include <stdio.h>
  8. #include <dir.h>
  9. #include <bios.h>
  10. #include <io.h>
  11. #include <string.h>
  12. #include <stdlib.h>
  13.  
  14. #include "tvapi.h"      /* types and function prototypes */
  15. #include "tvstream.h"
  16. #include "dvp.h"
  17. #include "tvui.h"
  18.  
  19. #if __TURBOC__ != 1 && __TURBOC__ != 0x0100
  20. unsigned _heaplen = 8192 ;  /* only need 8K heap */
  21. #endif
  22.  
  23. /*===============================================================*/
  24. /* global variables                                              */
  25. /*===============================================================*/
  26.  
  27. char old_title[24] ;
  28. int old_frattr ;
  29. int orig_rows,orig_cols ;
  30. int orig_row,orig_col ;
  31. int org_row, org_col ;
  32. int orig_lrows,orig_lcols ;
  33.  
  34. /*===============================================================*/
  35. /* write an integer out to the current task's main window as a   */
  36. /* decimal value                                                 */
  37. /* We can't use itoa(), because that assumes SS == DS in small   */
  38. /* data models, which winds up clobbering stuff when called from */
  39. /* inside the notify handler                                     */
  40. /*===============================================================*/
  41.  
  42. void write_int(int i)
  43. {
  44.    static char s[8] ;  /* must be in DS, but SS != DS inside notify handler */
  45.    int  neg = FALSE ;
  46.    int  count = 0 ;
  47.  
  48.    if (i < 0)          /* if number negative, then display a minus sign, */
  49.       {                /* followed by the additive inverse of the number */
  50.       neg = TRUE ;
  51.       i = -i ;
  52.       } ;
  53.    do                                /* convert the number to a string of chars */
  54.       {                              /* by repeatedly dividing by 10 and        */
  55.       s[count++] = (i % 10) + '0' ;  /* converting the remainder to a character */
  56.       i /= 10 ;                      /* produces reverse of char string for #   */
  57.       }
  58.    while (i > 0) ;
  59.    if (neg)
  60.       TVputchar(NIL,'-',7) ;
  61.    for ( count-- ; count >= 0 ; )   /* print the reverse of the stored string, which */
  62.       TVputchar(NIL,s[count--],7) ; /* results in the number in the correct order    */
  63. }
  64.  
  65. /*===============================================================*/
  66. /* wait for a keystroke, ensuring that the physical cursor pos   */
  67. /* is updated first (the logical cursor may move without         */
  68. /* necessarily moving the physical cursor)                       */
  69. /*===============================================================*/
  70.  
  71. int get_key(void)
  72. {
  73.    TVwin_hcur(NIL) ;
  74.    return bioskey(0) ;
  75. }
  76.  
  77. /*===============================================================*/
  78. /* save as much of the current state as we can, to restore later */
  79. /*===============================================================*/
  80.  
  81. void save_state(void)
  82. {
  83.    TVqry_origin(NIL,&org_row,&org_col) ;
  84.    TVqry_position(NIL,&orig_row,&orig_col) ;
  85.    TVqry_size(NIL,&orig_rows,&orig_cols) ;
  86.    TVqry_lsize(NIL,&orig_lrows,&orig_lcols) ;
  87.    TVqry_title(NIL,old_title,sizeof(old_title)) ;
  88.    old_frattr = TVqry_frattr(NIL) ;
  89. }
  90.  
  91. /*===============================================================*/
  92.  
  93. void standard_window(void)
  94. {
  95.    TVwin_resize(NIL,13,66) ;
  96.    TVwin_move(NIL,7,5) ;
  97.    TVwin_cursor(NIL,0,0) ;
  98.    TVwin_origin(NIL,0,0) ;
  99.    TVwin_clear(NIL) ;
  100. }
  101.  
  102. /*===============================================================*/
  103.  
  104. void stream_test(void)
  105. {
  106.    int row, col ;
  107.    char buffer[10] ;
  108.    int i ;
  109.  
  110.    standard_window() ;
  111.    TVwin_title(NIL,"DV-GLUE v" DVGLUE_versionSTR) ;
  112.    TVwin_frattr(NIL,9) ;
  113.    TVwin_redraw(NIL) ;
  114.    TVwin_printf(NIL,"Window #%d, old name was %s, origin (%d,%d)\r\n", DVappnum(), old_title, org_row,org_col) ;
  115.    TVqry_cursor(NIL,&row,&col) ;
  116.    TVwin_printf(NIL,"Cursor position is (%d,%d)\r\n",row,col) ;
  117.    TVqry_position(NIL,&row,&col) ;
  118.    TVwin_printf(NIL,"Window is at (%d,%d) ",row,col) ;
  119.    TVqry_size(NIL,&row,&col) ;
  120.    TVwin_printf(NIL,"and is %dx%d",row,col) ;
  121.    TVqry_lsize(NIL,&row,&col) ;
  122.    TVwin_printf(NIL,"/%dx%d in physical/logical size\r\n",row,col) ;
  123.    TVwin_printf(NIL,"The current output attribute is %d\r\n",TVqry_attr(NIL)) ;
  124.    TVwin_printf(NIL,"The old frame attribute was %d\r\n",old_frattr) ;
  125.    TVwin_printf(NIL,"Control code processing is %s",TVqry_ctrl(NIL)?"on":"off") ;
  126.    TVwin_printf(NIL," and we are \r\n  %s when writing\r\n",TVqry_leave(NIL)?
  127.                                        "leaving attributes untouched":"changing attributes") ;
  128.    TVwin_printf(NIL,"Using %s attributes\r\n",TVqry_logattr(NIL)?"logical":"physical") ;
  129.    TVwin_hcur(NIL) ;
  130.    TVwin_atread(NIL,FALSE) ;
  131.    TVqry_cursor(NIL,&row,&col) ;
  132.    TVwin_cursor(NIL,0,0) ;
  133.    TVwin_nread(NIL,(void *)buffer,sizeof(buffer)) ;
  134.    TVwin_cursor(NIL,row,col) ;
  135.    TVwin_printf(NIL,"First method read '%s' from screen\n",buffer) ;
  136.    TVwin_cursor(NIL,0,0) ;
  137.    TVwin_read(NIL,(void *)buffer,sizeof(buffer)) ;
  138.    TVwin_gotoxy(NIL,col,row+1) ;
  139.    TVwin_printf(NIL,"Second method read '%s' from screen\n",buffer) ;
  140.  
  141.    TVwin_swrite(NIL,"\r\nPress a key to hide window, then another to unhide it....");
  142.    get_key() ;
  143.    TVwin_hide(NIL) ;
  144.    get_key() ;
  145.    TVwin_unhide(NIL) ;
  146.    TVwin_swrite(NIL,"\r\nPress a key to continue..." ) ;
  147.    get_key() ;
  148.  
  149. /* now scroll the visible portion of the virtual screen left until it is clear */
  150.  
  151.    TVqry_size(NIL,&row,&col) ;
  152.    for (i = 0 ; i < col ; i++)
  153.       {
  154.       TVsleep(5) ;
  155.       TVwin_scroll(NIL,0,0,row,col,SCRL_LEFT) ;
  156.       }
  157. }
  158.  
  159. /*===============================================================*/
  160.  
  161. void timer_test(void)
  162. {
  163.    OBJECT k, t, w ;
  164.    int left, elapsed ;
  165.  
  166.    standard_window() ;
  167.    w = TVwin_new(NIL,5,46) ;
  168.    TVwin_clear(w) ;
  169.    TVposwin(w,NIL,PW_HCENTER|PW_VCENTER,0,0) ;
  170.    TVwin_cursor(w,0,0) ;
  171.    TVwin_origin(w,0,0) ;
  172.    TVwin_top(w) ;
  173.    TVwin_printf(w,"Press a few keys during the next ten seconds:"
  174.                   "\r\n(this doesn't work as expected)") ;
  175.    k = TVkbd_new() ;
  176.    TVkbd_write(k,"a",1,0) ;  /* make sure we allocate a buffer */
  177.    TVkbd_open(k,w) ;         /* before connecting to window */
  178.                              /* (to force one buffer per keystroke) */
  179.    TVkbd_setflags(k,KBD_ACTIVE) ;
  180.    t = TVtimer_new() ;
  181.    TVtimer_begin(t,1000) ;  /* 10 seconds */
  182.    while ((left = (int) TVtimer_len(t)) > 0)
  183.       {
  184.       elapsed = (int) TVtimer_elapsed(t) ;
  185.       TVwin_cursor(w,3,0) ;
  186.       TVwin_printf(w,"Time left: %2d.%02d  Buffers used: %d\r\n  Elapsed: %2d.%02d",
  187.                        left/100, left%100, TVkbd_messages(k), elapsed/100,
  188.                        elapsed%100) ;
  189.       }
  190.    TVtimer_free(t) ;
  191.    TVkbd_clear(k) ;  /* get rid of typeahead */
  192.    TVwin_cursor(w,0,0) ;
  193.    TVwin_printf(w,"%5d buffers used after clearing typeahead   \r\n",TVkbd_messages(k));
  194.    while (bioskey(1))  /* brute-force keyboard clear */
  195.       bioskey(0) ;
  196.    TVsleep(100) ;
  197.    TVkbd_free(k) ;
  198.    TVwin_free(w) ;
  199.    TVkbd_setflags(NIL,KBD_ACTIVE) ;   /* open and make active again */
  200. }
  201.  
  202. /*===============================================================*/
  203.  
  204. void notify_func(NOTIFY_MSG far *msg)
  205. {
  206.    static char mail[2] ;
  207.  
  208.    /* at this point, we are on the private stack, not our own */
  209.    /* switching to our prior stack causes a crash */
  210.  
  211.    /* NOTE: can't use TVwin_printf unless we can ensure that it isn't used in */
  212.    /* any routines which might be interrupted for this notification */
  213.    /* also need to be careful with any routines that need SS == DS in small */
  214.    /* data models */
  215.  
  216.    TVwin_swrite(NIL,"\r\n                                                                 \r") ;
  217.    switch (msg->event)
  218.       {
  219.       case TV_HMOVE:
  220.       case TV_VMOVE:
  221.                TVwin_swrite(NIL,"Hey, don't move me!  Now at ") ;
  222.                write_int(msg->msg.movement.row) ;
  223.                TVwin_swrite(NIL,",") ;
  224.                write_int(msg->msg.movement.col) ;
  225.                break ;
  226.       case TV_HSIZE:
  227.       case TV_VSIZE:
  228.                TVwin_swrite(NIL,"I liked my previous size!  New size ") ;
  229.                write_int(msg->msg.resizing.rows) ;
  230.                TVwin_swrite(NIL," by ") ;
  231.                write_int(msg->msg.resizing.cols) ;
  232.                break ;
  233.       case TV_HSCROLL:
  234.                TVwin_swrite(NIL,"You scrolled me ") ;
  235.                if (msg->msg.scrolling.amount > 0)
  236.                   TVwin_swrite(NIL,"right") ;
  237.                else if (msg->msg.scrolling.amount < 0)
  238.                   TVwin_swrite(NIL,"left") ;
  239.                else
  240.                   TVwin_swrite(NIL,"[done]") ;
  241.                break ;
  242.       case TV_VSCROLL:
  243.                TVwin_swrite(NIL,"You scrolled me ") ;
  244.                if (msg->msg.scrolling.amount > 0)
  245.                   TVwin_swrite(NIL,"down") ;
  246.                else if (msg->msg.scrolling.amount < 0)
  247.                   TVwin_swrite(NIL,"up") ;
  248.                else
  249.                   TVwin_swrite(NIL,"[done]") ;
  250.                break ;
  251.       case TV_CLOSE:
  252.                TVwin_swrite(NIL,"You can't close me yet!  Next time WILL close me") ;
  253.                TVwin_cancel(NIL,TV_CLOSE) ;
  254.                break ;
  255.       case TV_HIDE:
  256.                TVwin_swrite(NIL,"You hid me!") ;
  257.                break ;
  258.       case TV_HELP:
  259.                TVwin_swrite(NIL,"Sorry, no help available.  Mouse at (") ;
  260.                write_int(msg->msg.help.mouse_row) ;
  261.                TVwin_swrite(NIL,",") ;
  262.                write_int(msg->msg.help.mouse_col) ;
  263.                TVwin_swrite(NIL,")") ;
  264.                break ;
  265.       case TV_COLORS:
  266.                TVwin_swrite(NIL,"Was the color changed?") ;
  267.                break ;
  268.       case TV_SWITCHEDTO:
  269.                TVwin_swrite(NIL,"Thanks for making me active.") ;
  270.                break ;
  271.       case TV_SWITCHEDAWAY:
  272.                TVwin_swrite(NIL,"Hey, I want to stay active!") ;
  273.                break ;
  274.       case TV_VIDEOMODE:
  275.                TVwin_swrite(NIL,"New video mode is ") ;
  276.                write_int(msg->msg.video_mode) ;
  277.                break ;
  278.       case TV_SCISSORS_CUT:
  279. /*               while (TVmbx_size(msg->msg.scissors.mailbox) > 0)
  280.                   TVmbx_write(msg->msg.scissors.mailbox,0,0,"",0) ;  /* keep DV happy */
  281.                TVwin_swrite(NIL,"Sorry, don't know how to cut (") ;
  282.                write_int(msg->msg.scissors.up_left_row) ;
  283.                TVwin_swrite(NIL,",") ;
  284.                write_int(msg->msg.scissors.up_left_col) ;
  285.                TVwin_swrite(NIL,") to (") ;
  286.                write_int(msg->msg.scissors.up_left_row + msg->msg.scissors.height - 1) ;
  287.                TVwin_swrite(NIL,",") ;
  288.                write_int(msg->msg.scissors.up_left_col + msg->msg.scissors.width - 1) ;
  289.                TVwin_swrite(NIL,")") ;
  290.                break ;
  291.       case TV_SCISSORS_COPY:
  292. /*               while (TVmbx_size(msg->msg.scissors.mailbox) > 0)
  293.                   TVmbx_write(msg->msg.scissors.mailbox,0,0,"",0) ;  /* keep DV happy */
  294.                TVwin_swrite(NIL,"Sorry, don't know how to copy (") ;
  295.                write_int(msg->msg.scissors.up_left_row) ;
  296.                TVwin_swrite(NIL,",") ;
  297.                write_int(msg->msg.scissors.up_left_col) ;
  298.                TVwin_swrite(NIL,") to (") ;
  299.                write_int(msg->msg.scissors.up_left_row + msg->msg.scissors.height - 1) ;
  300.                TVwin_swrite(NIL,",") ;
  301.                write_int(msg->msg.scissors.up_left_col + msg->msg.scissors.width - 1) ;
  302.                TVwin_swrite(NIL,")") ;
  303.                break ;
  304.       case TV_SCISSORS_PASTE:
  305. /*               (void) TVreadmail(msg->msg.scissors.mailbox,mail,0) ;  /* keep DV happy */
  306.                TVwin_swrite(NIL,"Sorry, don't know how to paste (") ;
  307.                write_int(msg->msg.scissors.up_left_row) ;
  308.                TVwin_swrite(NIL,",") ;
  309.                write_int(msg->msg.scissors.up_left_col) ;
  310.                TVwin_swrite(NIL,") to (") ;
  311.                write_int(msg->msg.scissors.up_left_row + msg->msg.scissors.height - 1) ;
  312.                TVwin_swrite(NIL,",") ;
  313.                write_int(msg->msg.scissors.up_left_col + msg->msg.scissors.width - 1) ;
  314.                TVwin_swrite(NIL,")") ;
  315.                break ;
  316.       case TV_MAINMENU:
  317.                TVwin_swrite(NIL,"Main menu popped up") ;
  318.                break ;
  319.       case TV_MENU_END:
  320.                TVwin_swrite(NIL,"Main menu put away") ;
  321.                break ;
  322.       default: TVwin_swrite(NIL,"Unknown event ") ;
  323.                write_int(msg->event) ;
  324.                TVwin_swrite(NIL,"!  What happened?") ;
  325.                break ;
  326.       }
  327. }
  328.  
  329. void far notify_handler(void)
  330. {
  331.    static NOTIFY_MSG msg ; /* TVreadmail needs to have msg in DS, which is != SS */
  332.  
  333.    /* at this point, we are on the private stack, not our own */
  334.    /* switching to our prior stack causes a crash */
  335.    while (TVmbx_size(NIL))
  336.       if (TVreadmail(NIL,(char *)&msg,sizeof(msg)) > 0)
  337.          {
  338.          msg.event -= MS_NOTIFY ;
  339.          notify_func((NOTIFY_MSG far *)&msg) ;  /* far to ensure proper segment, */
  340.                                                 /* since DS != SS in small models */
  341.          }
  342. }
  343.  
  344. void notify_test(void)
  345. {
  346.    int i ;
  347.    char far *scrnbuf ;
  348.    int size, flag ;
  349.    int row, col ;
  350.  
  351.    standard_window() ;
  352.    TVwin_redraw(NIL) ;
  353. /* select whether to use TVwin_notify or UIsignal.  Change the 0 to 1 to use */
  354. /* TVwin_notify */
  355. #if 0
  356.    TVwin_async(NIL,notify_handler) ;
  357.    for (i = TV_HMOVE ; i <= TV_SWITCH ; i++)
  358.       {
  359.       TVwin_allow(NIL,i) ;
  360.       TVwin_notify(NIL,i) ;
  361.       }
  362. #else
  363.    for (i = TV_HMOVE ; i <= TV_MENU_END ; i++)
  364.       UIsignal(i,NIL,notify_func) ;
  365. #endif 0
  366.    TVwin_disallow(NIL,TV_QUIT) ;
  367.    TVwin_swrite(NIL,"\r\nJust try to do something to me! (including closing me)\r\n"
  368.                     "(Rearrange/Hide after using Scissors may lock up your system)") ;
  369.    TVwin_cursor(NIL,4,0) ;
  370.    TVwin_swrite(NIL,"Press a key when done....\r\n") ;
  371.    TVwin_hcur(NIL) ;
  372.    TVgetbuf(NIL,&scrnbuf,&size,&flag) ;
  373.    while (bioskey(1) == 0)
  374.       {
  375.       switch (scrnbuf[0])
  376.          {
  377.          case '|': scrnbuf[0] = '/' ;
  378.                    break ;
  379.          case '/': scrnbuf[0] = '-' ;
  380.                    break ;
  381.          case '-': scrnbuf[0] = '\\' ;
  382.                    break ;
  383.          default:  scrnbuf[0] = '|' ;
  384.          }
  385.       TVqry_cursor(NIL,&row,&col) ;
  386.       if (row > 20)
  387.          TVwin_cursor(NIL,5,0) ;
  388.       TVsleep(20) ;
  389.       }
  390.    bioskey(0) ;
  391.    for (i = TV_HMOVE ; i <= TV_SWITCH ; i++)
  392.       TVwin_cancel(NIL,i) ;  /* cancel notification */
  393.    TVwin_allow(NIL,TV_QUIT) ;
  394.    TVwin_clear(NIL) ;
  395. }
  396.  
  397. /*===============================================================*/
  398.  
  399. void pointer_test(void)
  400. {
  401.    OBJECT p ;
  402.    int i, rows, cols ;
  403.  
  404.    TVwin_title(NIL,"Mouse Demo") ;
  405.    standard_window() ;
  406.    TVwin_move(NIL,1,1) ;
  407.    TVwin_top(NIL) ;
  408.    TVwin_redraw(NIL) ;
  409.    p = TVptr_new() ;
  410.    TVptr_open(p,NIL) ;
  411.    TVptr_icon(p,'+') ;  /* this is actually ignored in DV, I assume it does work */
  412.                         /* as advertised under TopView */
  413.    TVwin_disallow(NIL,TV_HSIZE) ;
  414.    TVwin_disallow(NIL,TV_VSIZE) ;
  415.    if (TVqry_kmouse())      /* if we are using a keyboard mouse */
  416.       TVapi_kmouse(TRUE) ;  /* make sure it is on */
  417.    TVwin_swrite(NIL,"\r\nMoving mouse pointer to screen origin") ;
  418.    TVsleep(100) ;
  419.    TVqry_position(NIL,&rows,&cols) ;
  420.    TVptr_goto(p,-rows,-cols) ;
  421.    TVsleep(100) ;
  422.    TVwin_swrite(NIL,"\r\nMoving mouse pointer to positions relative to window\r\n");
  423.    TVqry_size(NIL,&rows,&cols) ;
  424.    for (i = 0 ; i < rows ; i++)
  425.       {
  426.       TVptr_goto(p,i,i/2+1) ;
  427.       TVsleep(25) ;
  428.       }
  429.    TVwin_allow(NIL,TV_VSIZE) ;
  430.    TVwin_allow(NIL,TV_HSIZE) ;
  431.    TVptr_getscale(p,&rows,&cols) ;
  432.    TVwin_printf(NIL,"\r\nPointer scaling: %d rows and %d columns",rows,cols) ;
  433.    TVsleep(100) ;
  434.    TVptr_free(p) ;
  435.    if (TVqry_kmouse())      /* if we are using a keyboard mouse */
  436.       TVapi_kmouse(FALSE) ; /* make sure it is off */
  437.    TVwin_bottom(NIL) ;
  438. }
  439.  
  440. void mouse_drawing_program(void)
  441. {
  442.    OBJECT p ;
  443.    POINTER_MSG msg ;
  444.    int left_button = FALSE ;
  445.    int right_button = FALSE ;
  446.  
  447.    TVwin_clear(NIL) ;
  448.    TVwin_cursor(NIL,0,0) ;
  449.    TVwin_top(NIL) ;
  450.    TVwin_resize(NIL,23,47) ;
  451.    TVwin_move(NIL,1,10) ;
  452.    TVwin_swrite(NIL,"Drawing Program.             Press key to quit\r\n"
  453.                     " Left button sets block, right button erases\r\n"
  454.                     "       Row:    4 Col:    0 Buttons:   \r\n"
  455.                     "----------------------------------------------\r\n") ;
  456.    TVwin_redraw(NIL) ;
  457.    p = TVptr_new() ;
  458.    TVptr_open(p,NIL) ;
  459.    TVptr_setflags(p,PTR_RELEASE|PTR_NOTTOP) ;
  460.    if (TVqry_kmouse())      /* if we are using a keyboard mouse */
  461.       TVapi_kmouse(TRUE) ;  /* make sure it is on */
  462.    TVptr_goto(p,4,0) ;
  463.    msg.row = 4 ; msg.column = 0 ; msg.button_state = 0 ;
  464.    while (bioskey(1) == 0)
  465.       if (TVptr_messages(p) != 0)  /* only read pointer if there is input */
  466.          {
  467.          TVptr_read(p,&msg) ;
  468.          if (msg.button_state & 1)
  469.             {
  470.             if (msg.button_state & 0x80)
  471.                left_button = TRUE ;
  472.             else if (msg.button_state & 0x40)
  473.                left_button = FALSE ;
  474.             }
  475.          else if (msg.button_state & 2)
  476.             if (msg.button_state & 0x80)
  477.                right_button = TRUE ;
  478.             else if (msg.button_state & 0x40)
  479.                right_button = FALSE ;
  480.          if (msg.row >= 4 && msg.row < 23 && msg.column >= 0 && msg.column < 46)
  481.             {
  482.             TVwin_cursor(NIL,msg.row,msg.column) ;
  483.             if (left_button)
  484.                TVputchar(NIL,'█',7) ;
  485.             else if (right_button)
  486.                TVputchar(NIL,' ',7) ;
  487.             }
  488.          if (msg.row < 4)
  489.             {
  490.             TVptr_goto(p,4,msg.column) ;
  491.             msg.row = 4 ;
  492.             }
  493.          TVwin_cursor(NIL,2,7) ;
  494.          TVwin_printf(NIL,"Row: %4d Col: %4d Buttons: %c%c", msg.row, msg.column,
  495.                         left_button ? 'L' : ' ',right_button ? 'R' : ' ') ;
  496.          }
  497.    bioskey(0) ;  /* swallow the keystroke */
  498.    TVptr_close(p) ;
  499.    TVptr_free(p) ;
  500.    if (TVisobj(p))
  501.       TVerrormsg(0,"Error--Pointer wasn't freed!",1,0,0,0) ;
  502.    else
  503.       {
  504.       TVwin_cursor(NIL,22,0) ;
  505.       TVwin_swrite(NIL,"Press a key to continue....") ;
  506.       get_key() ;
  507.       }
  508.    if (TVqry_kmouse())      /* if we are using a keyboard mouse */
  509.       TVapi_kmouse(FALSE) ; /* make sure it is off */
  510.    TVwin_bottom(NIL) ;
  511. }
  512.  
  513. /*===============================================================*/
  514.  
  515. void multiwindow_test(void)
  516. {
  517.    OBJECT win1 = TVwin_new(NIL,10,15) ;
  518.    OBJECT win2 = TVwin_new(NIL,5,20) ;
  519.    OBJECT win3 = TVwin_new(NIL,8,30) ;
  520.  
  521.    standard_window() ;
  522.    TVwin_redraw(NIL) ;
  523.    TVwin_move(win1,6,60) ;
  524.    TVwin_title(win1,"Window 1") ;
  525.    TVwin_redraw(win1) ;
  526.    TVwin_move(win2,1,52) ;
  527.    TVwin_title(win2,"Window 2") ;
  528.    TVwin_redraw(win2) ;
  529.    TVwin_move(win3,4,40) ;
  530.    TVwin_title(win3,"Window 3") ;
  531.    TVwin_redraw(win3) ;
  532.    TVwin_title(NIL,"Multiwindow Demo") ;
  533.    TVwin_redraw(NIL) ;
  534.    TVsleep(150) ;
  535.    TVwin_reorder(win1,OBJSEG(win3),OBJSEG(win2),OBJSEG(TVmywindow()),OBJSEG(win1),0);
  536.    TVwin_swrite(win1,"Window 1 on top") ;
  537.    TVsleep(150) ;
  538.    TVwin_reorder(win3,OBJSEG(win2),OBJSEG(win1),OBJSEG(TVmywindow()),OBJSEG(win3),0);
  539.    TVwin_swrite(win3,"Window 3 on top") ;
  540.    TVsleep(150) ;
  541.    TVwin_reorder(win2,OBJSEG(win3),OBJSEG(TVmywindow()),OBJSEG(win1),OBJSEG(win2),0);
  542.    TVwin_swrite(win2,"Window 2 on top") ;
  543.    TVsleep(150) ;
  544.    TVwin_reorder(NIL,OBJSEG(win2),OBJSEG(win3),OBJSEG(win1),OBJSEG(TVmywindow()),0);
  545.    TVwin_swrite(NIL,"\r\nWindow 0 on top") ;
  546.    TVsleep(100) ;
  547.    TVwin_top(win3) ;
  548.    TVwin_swrite(win3,"\n\rWindow 3 on top again") ;
  549.    TVsleep(100) ;
  550.    TVwin_topsys(win2) ;
  551.    TVwin_swrite(win2,"\n\rWindow 2 now topmost" ) ;
  552.    TVsleep(100) ;
  553.    TVwin_top(NIL) ;
  554.    TVwin_swrite(NIL,"\n\rBack to window 0" ) ;
  555.    TVsleep(100) ;
  556.    TVwin_swrite(NIL,"\r\nPlease open another window, then press a key....") ;
  557.    TVwin_top(NIL) ;  /* need to be topmost to have keyboard attached */
  558.    get_key() ;
  559.    TVwin_swrite(NIL,"\n\rAbout to hide and then unhide all my windows....") ;
  560.    TVsleep(150) ;
  561.    TVapp_hide(NIL) ;    /* also puts us in background, */
  562.    TVsleep(100) ;
  563.    TVapp_show(NIL) ;
  564.    TVsleep(10) ;
  565.    TVapp_gofore(NIL) ;  /* so have to force ourself into foreground */
  566.    TVwin_swrite(NIL,"\r\nDone!") ;
  567.    TVwin_redraw(NIL) ;
  568.    TVsleep(50) ;
  569.    TVwin_swrite(NIL,"\r\n\nI am about to put myself in the background, and"
  570.                     "\r\nthen back into the foreground") ;
  571.    TVsleep(200) ;
  572.    TVapp_goback(NIL) ;
  573.    TVsleep(100) ;
  574.    TVapp_gofore(NIL) ;
  575.    TVwin_swrite(NIL,"\r\nDone!") ;
  576.    TVsleep(50) ;
  577.    TVwin_free(win3) ;
  578.    TVsleep(50) ;
  579.    TVwin_free(win2) ;
  580.    TVsleep(50) ;
  581.    TVwin_free(win1) ;
  582.    TVsleep(50) ;
  583.    TVwin_frattr(NIL,0x70) ;  /* reverse video */
  584.    TVwin_top(NIL) ;          /* make window active */
  585.    TVwin_redraw(NIL) ;       /* make sure physical screen is updated */
  586.    TVwin_swrite(NIL,"\r\nPress a key to continue....") ;
  587.    get_key() ;
  588. }
  589.  
  590. /*===============================================================*/
  591.  
  592. void subtask1(int parent)
  593. {
  594.    char kbd_input[16] ;
  595.    char mbx_input[32] ;
  596.    int mbx_status ;
  597.    OBJECT mbx ;
  598.  
  599.    do {
  600.       TVkbd_read(NIL,kbd_input,sizeof(kbd_input)) ;
  601.       if (kbd_input[0] != 0x1B)
  602.          TVwin_swrite(NIL,kbd_input) ;
  603.       } while (kbd_input[0] != 0x1B) ;
  604.    TVwin_clear(NIL) ;
  605.    do {
  606.       TVreadmail(NIL,mbx_input, sizeof(mbx_input)) ;
  607.       mbx_status = (int) TVmbx_status(NIL) ;
  608.       if (mbx_input[0] == '\0')
  609.          TVwin_swrite(NIL,"\r\nThat's all, folks!" ) ;
  610.       else
  611.          {
  612.          TVwin_printf(NIL, "\r\nRead: '%s' with status %d",mbx_input,mbx_status) ;
  613.          if (OBJSEG(TVmbx_sender(NIL)) == parent)
  614.             TVwin_swrite(NIL," from parent") ;
  615.          else
  616.             TVwin_swrite(NIL," from a stranger") ;
  617.          }
  618.       } while (mbx_input[0] != '\0') ;
  619.    TVsleep(250) ;
  620.    TVwin_clear(NIL) ;
  621.    TVwin_swrite(NIL,"Test of named mailboxes:\r\n") ;
  622.    mbx = TVmbx_new() ;
  623.    TVmbx_open(mbx);
  624.    TVmbx_name(mbx,"Test Mailbox") ;
  625.    TVmbx_clear(mbx) ;
  626.    TVmbx_write(TVmbxof(MK_OBJ(parent)),FALSE,0,"Ready",5) ;
  627.    TVreadmail(mbx,mbx_input,sizeof(mbx_input)) ;
  628.    TVwin_swrite(NIL,"Got '") ;
  629.    TVwin_swrite(NIL,mbx_input) ;
  630.    TVwin_swrite(NIL,"'") ;
  631.    TVsleep(150) ;  /* don't ACK right away */
  632.    TVmbx_write(TVmbxof(MK_OBJ(parent)),FALSE,0,"Done",4) ;
  633.    TVreadmail(NIL,mbx_input,sizeof(mbx_input)) ;
  634.    TVmbx_close(mbx) ;
  635.    TVmbx_free(mbx) ;
  636. }
  637.  
  638. void subtask2(int parent)
  639. {
  640.    int row = 0, col = 0 ;
  641.    int drow, dcol ;
  642.    int rows, cols ;
  643.    int rep ;
  644.  
  645.    (void) parent ;  /* get rid of TurboC's warning about unused parameters */
  646.    TVwin_cursor(NIL,0,0) ;
  647.    TVwin_hcur(NIL) ;
  648.    drow = 1 ;
  649.    dcol = 1 ;
  650.    for (rep = 0 ; rep < 30 ; rep++)
  651.       do {
  652.          if (TVmbx_size(NIL) != 0)
  653.             {
  654.             TVmbx_clear(NIL) ;  /* discard messages, only used to notify us */
  655.             TVtask_stop(NIL) ;   /* and suspend ourselves */
  656.             }
  657.          TVwin_cursor(NIL,row,col) ;
  658.          TVwin_swrite(NIL," ") ;
  659.          TVqry_size(NIL, &rows, &cols) ;
  660.          if (row < 0 || row >= rows-1)
  661.             drow = -drow ;
  662.          if (col < 0 || col >= cols-1)
  663.             dcol = -dcol ;
  664.          row += drow ;
  665.          col += dcol ;
  666.          TVwin_cursor(NIL,row,col) ;
  667.          TVwin_swrite(NIL,"+") ;
  668.          TVsleep(10) ;
  669.          } while (row != 0 || col != 0) ;
  670. }
  671.  
  672. void stripCRLF(char *buf)
  673. {
  674.    char *s = buf + strlen(buf) -1 ;
  675.  
  676.    while (s >= buf && (*s == '\r' || *s == '\n'))
  677.       s-- ;
  678.    s[1] = '\0' ;
  679. }
  680.  
  681. DVP_file DVPbuffer ;
  682. char prog[40], arg1[40] ;
  683.  
  684. void app_new_test(void)
  685. {
  686.    char *progname ;
  687.    OBJECT new_task ;
  688.  
  689.    TVwin_clear(NIL) ;
  690.    TVwin_cursor(NIL,0,0) ;
  691.    TVwin_swrite(NIL,"\r\nOK, now let's load a user program.\r\nProgram's name, including extension: ");
  692.    TVwin_hcur(NIL) ;
  693.    fgets(prog,sizeof(prog),stdin) ;
  694.    stripCRLF(prog) ;
  695.    TVwin_swrite(NIL,"\r\nThe program's argument: " ) ;
  696.    TVwin_hcur(NIL) ;
  697.    fgets(arg1,sizeof(arg1),stdin) ;
  698.    stripCRLF(arg1) ;
  699.    progname = searchpath(prog) ;
  700.    if (progname)
  701.       {
  702.       TVwin_printf(NIL,"\nInvoking '%s %s'\n",progname,arg1) ;
  703.       new_task = TVapp_new(NIL,10,1,13,78,TRUE,progname,progname,arg1,NULL) ;
  704.       if (new_task != NIL)
  705.          {
  706.          TVwin_swrite(NIL,"\r\nExperiment with switching between this program and "
  707.                           "\r\nthe one you just invoked.  Press a key when done") ;
  708.          get_key() ;
  709.          TVtask_free(new_task) ;
  710.          }
  711.       else
  712.          TVerrormsg(0,"Error loading--not enough memory?  ESC to continue",1,0,0,0) ;
  713.       }
  714.    else
  715.       {
  716.       TVwin_printf(NIL,"\n\n\nCouldn't find %s!\n", prog ) ;
  717.       TVsleep(150) ;
  718.       }
  719. }
  720.  
  721. void app_start_test(void)
  722. {
  723.    int size ;
  724.    FILE *fp ;
  725.  
  726.    standard_window() ;
  727.    TVwin_title(NIL,"Create new Window") ;
  728.    TVwin_swrite(NIL,"This next test may cause your system to lock up.\r\n"
  729.                     "It is known to cause a lockup the next time you\r\n"
  730.                     "try to open a window under DV 2.00 (6-16-87)\r\n"
  731.                     "\r\n"
  732.                     "Type the keys from the open menu, or just Return to\r\n"
  733.                     "skip this test\r\n"
  734.                     "\r\n"
  735.                     "Keys on open menu: ") ;
  736.    TVwin_redraw(NIL) ;
  737.    fgets(arg1,sizeof(arg1),stdin) ;
  738.    if (arg1[0] && arg1[0] != '\n')
  739.       {
  740.       arg1[2] = '\0' ;
  741.       TVwin_swrite(NIL,"DV directory (i.e. C:\\DV): ") ;
  742.       TVwin_hcur(NIL) ;
  743.       fflush(stdin) ;
  744.       fgets(prog,sizeof(prog)-11,stdin) ;
  745.       if (prog[strlen(prog)-1] == '\n')
  746.          prog[strlen(prog)-1] = '\0' ;
  747.       strcat(prog,"\\") ;
  748.       strcat(prog,arg1) ;
  749.       strcat(prog,"-PIF.DVP") ;
  750.       if ((fp = fopen(prog,"rb")) == NULL)
  751.          TVwin_printf(NIL,"\r\nUnable to open %s!\r\n",prog) ;
  752.       else
  753.          {
  754.          size = fread(&DVPbuffer,1,sizeof(DVPbuffer),fp) ;
  755.          if (DVapp_start(&DVPbuffer,size) == 0)
  756.             TVwin_swrite(NIL,"Unable to open!\r\n") ;
  757.          fclose(fp) ;
  758.          }
  759.       TVwin_swrite(NIL,"Press a key....") ;
  760.       get_key() ;
  761.       }
  762. }
  763.  
  764. void fork_test(void)
  765. {
  766.    char key, keys[2] ;
  767.    OBJECT task1, task2 ;
  768.    int count = 0 ;
  769.    char mail[10] ;
  770.  
  771.    standard_window() ;
  772.    TVwin_resize(NIL,8,66) ;
  773.    TVwin_move(NIL,5,11) ;
  774.    TVwin_redraw(NIL) ;
  775.    task1 = TVtask_new(NIL,"Echo keys",1,39,3,40,NULL,1000,subtask1,FALSE) ;
  776.    if (task1 == NIL)
  777.       {
  778.       TVerrormsg(0,"Insufficient memory or other error--Press ESC",1,0,0,0);
  779.       return ;
  780.       }
  781.    task2 = TVtask_new(NIL,"Another task",14,1,10,78,NULL,1000,subtask2,FALSE) ;
  782.    if (task2 == NIL)
  783.       {
  784.       TVerrormsg(0,"Insufficient memory or other error--Press ESC",1,0,0,0) ;
  785.       TVtask_free(task1) ;
  786.       return ;
  787.       }
  788.    TVwin_top(NIL) ;  /* put the cursor back in our window */
  789.    TVwin_swrite(NIL,"Type characters to echo in other window, ESC to quit") ;
  790.    do {
  791.       key = get_key() ;
  792.       keys[0] = key ;
  793.       TVkbd_write(TVkbdof(task1),keys,1,0) ;
  794.       } while (key != 0x1B) ;
  795.    TVsleep(25) ;  /* allow time for other window to clear */
  796.    TVwin_swrite(NIL,"\r\nType strings to echo in other window, press just RETURN to quit\r\n") ;
  797.    TVwin_hcur(NIL) ;
  798.    do {
  799.       fgets(arg1, sizeof(arg1), stdin) ;
  800.       stripCRLF(arg1) ;
  801.       TVmbx_write(TVmbxof(task1),FALSE,count++,arg1, strlen(arg1)) ;
  802.    } while (strlen(arg1) > 0) ;
  803.  
  804.    TVmbx_clear(NIL) ;
  805.    TVwin_swrite(NIL,"\r\nTesting named mailboxes\r\n") ;
  806.    TVreadmail(NIL,mail,sizeof(mail)) ;  /* wait for other task to set up mbx */
  807.    TVwin_swrite(NIL,"sending... " ) ;
  808.    TVmbx_write(TVmbx_find("Test Mailbox"),FALSE,0,"Test successful",15) ;
  809.    TVreadmail(NIL,mail,sizeof(mail)) ;  /* wait for ACK */
  810.    TVwin_printf(NIL,"got ACK: '%s'",mail) ;
  811.    TVmbx_write(TVmbxof(task1),FALSE,0,"Quit",4) ;
  812.  
  813.    TVsleep(100) ;  /* allow time for other window to close */
  814.    TVwin_swrite(NIL,"\r\n\r\nPress a key to continue....") ;
  815.    get_key() ;
  816.    TVwin_move(NIL,1,1) ;
  817.    TVwin_resize(NIL,9,66) ;
  818.    TVwin_redraw(NIL) ;  /* update window's size and position on the screen */
  819.    TVsendmail(TVmbxof(task2),"",0) ;  /* would like to do TVtask_stop(task2) */
  820.                                       /* but DV 2.00 only allows suspending */
  821.                                       /* the current process, not others */
  822.    TVwin_clear(NIL) ;
  823.    TVwin_cursor(NIL,0,0) ;
  824.    TVwin_swrite(NIL,"\r\nThe 'bouncing' plus sign in the other window should"
  825.                     "\r\nhave stopped moving.  Press a key....") ;
  826.    get_key() ;
  827.    TVtask_start(task2) ;
  828.    TVwin_swrite(NIL,"\r\nIt should have started moving again.  Press a key....") ;
  829.    get_key() ;
  830.    TVtask_free(task1) ;
  831.    TVtask_free(task2) ;  /* make sure the subtasks are both terminated */
  832.    app_new_test() ;
  833.    app_start_test() ;
  834.    TVwin_clear(NIL) ;
  835. }
  836.  
  837. /*===============================================================*/
  838.  
  839. void far second_level_interrupt(void)
  840. {
  841.    /* note that in this routine, DS/ES/SS are unknown */
  842.    TVsound(1000,10) ;
  843. }
  844.  
  845. void interrupt_test(void)
  846. {
  847.    WORD bit = TVgetbit(second_level_interrupt) ;
  848.  
  849.    standard_window() ;
  850.    TVwin_swrite(NIL,"\r\n\r\nPress a key to test second level interrupts") ;
  851.    TVwin_redraw(NIL) ;
  852.    get_key() ;
  853.    TVwin_swrite(NIL,"\r\n\r\nBeeping....") ;
  854.    TVsetbit(bit) ;
  855.    TVsleep(100) ;
  856.    TVfreebit(bit) ;
  857.    TVwin_swrite(NIL,"Done!\r\n") ;
  858. }
  859.  
  860. /*===============================================================*/
  861.  
  862. void objectq_test(void)
  863. {
  864.    OBJECT p = TVptr_new() ;
  865.    OBJECT obj ;
  866.    char buffer[100] ;
  867.    int i, count ;
  868.    POINTER_MSG msg ;
  869.  
  870.    standard_window() ;
  871.    TVwin_redraw(NIL) ;
  872.    TVobq_open(NIL) ;
  873.    TVptr_open(p,NIL) ;
  874.    TVptr_setflags(p,PTR_NOTFORE|PTR_NOTTOP|PTR_RELEASE) ;
  875.    TVptr_erase(p) ;
  876.    TVobq_add(NIL,p) ;
  877.    TVkbd_clear(NIL) ;
  878.    TVkbd_setflags(NIL,KBD_CONCURRENT) ;
  879.    TVobq_add(NIL,TVmykbd()) ;
  880.    TVwin_clear(NIL) ;
  881.    TVwin_title(NIL,"OBJECTQ demo") ;
  882.    TVwin_cursor(NIL,0,0) ;
  883.    TVwin_origin(NIL,0,0) ;
  884.    TVwin_swrite(NIL,"Waiting for input from either the keyboard or a mouse\r\n") ;
  885.    TVwin_swrite(NIL,"(a keyboard mouse doesn't count as mouse input)") ;
  886.    obj = TVobq_read(NIL) ;
  887.    if (obj == p)
  888.       {
  889.       TVptr_read(obj,&msg) ;
  890.       TVwin_printf(NIL,"Got row: %d  col: %d  buttons: %02.2x\n",msg.row,
  891.                                                   msg.column,msg.button_state) ;
  892.       }
  893.    else
  894.       {
  895.       count = TVkbd_read(obj,buffer,sizeof(buffer)) ;
  896.       TVwin_swrite(NIL,"\r\nGot: ") ;
  897.       for (i = 0 ; i < count ; i++)
  898.          TVwin_printf(NIL,"%02x ",buffer[i]) ;
  899.       }
  900.    TVobq_remove(NIL,p) ;  /* don't take input from mouse anymore */
  901.    TVptr_close(p) ;       /* don't need the object, so free it */
  902.    TVptr_free(p) ;
  903.    TVsleep(100) ;
  904.    TVobq_close(NIL) ;
  905. }
  906.  
  907. /*===============================================================*/
  908.  
  909. extern WORD _restore_DS(void) ;
  910.  
  911. void far kbd_filter(void)
  912. {
  913.    WORD ax = _AX ;   /* store the parameters which were passed in registers */
  914.    WORD bx = _BX ;
  915.    WORD cx = _CX ;
  916.    WORD dx = _DX ;
  917.    WORD ds = _DS ;   /* and DS, which we will be clobbering */
  918.  
  919.    _restore_DS() ;   /* get back TurboC's data segment (not necessary in this */
  920.                      /* trivial filter function, though) */
  921.    /* tell DESQview to ignore non-numeric characters in numeric fields */
  922.    if ((dx & F_NUMBER) != 0 && ax >= ' ' && ax <= 0xFF)
  923.       ax = (ax >= '0' && ax <= '9') ? 0 : 0x100 ;
  924.    else if (ax > 0xFF)
  925.       ax = 0 ;  /* we want to use the extended-ASCII keystrokes */
  926.    _DX = dx ;
  927.    _CX = cx ;
  928.    _BX = bx ;
  929.    _DS = ds ;
  930.    _AX = ax ;
  931. }
  932.  
  933. /*===============================================================*/
  934.  
  935. void field_test(void)
  936. {
  937.    char buffer[50] ;
  938.    BYTE *fields ;
  939.    int status, len ;
  940.  
  941.    TVwin_title(NIL,"Field Demo") ;
  942.    standard_window() ;
  943.    TVwin_swrite(NIL,"Field-mode test\r\n"
  944.                     "Cursor should be  \031  there\r\n"
  945.                     "Enter a number:     Enter a string:\r\n"
  946.                     "Forced uppercase string:        With value: \r\n"
  947.                     "Press RETURN when done, or click here: ") ;
  948.    fields = TVfld_build_header(5,F_ALLOWKBD|F_READARRAY,0x70,0x0F) ;
  949.    TVfld_build_entry(fields,1,2,16,2,18,F_FILLIN,F_NEXT|F_NUMBER|F_CLEAR,1,0) ;
  950.    TVfld_build_entry(fields,2,2,35,2,50,F_FILLIN,F_NEXT|F_CLEAR|4,1,0) ;
  951.    TVfld_build_entry(fields,3,3,25,3,30,F_FILLIN,F_NEXT|F_UPPER|F_CLEAR,1,0) ;
  952.    TVfld_build_entry(fields,4,3,44,3,57,F_FILLIN,F_NEXT|F_CLEAR,1,0) ;
  953.    TVfld_build_entry(fields,5,4,39,4,42,F_MENU,'\r',0x70,0) ;
  954.    TVwin_stream(NIL,fields) ;
  955.    TVfld_swrite(NIL,4,"default") ;
  956.    TVfld_attr(NIL,4,0x70) ;
  957.    TVfld_cursor(NIL,1) ;   /* position cursor in first field */
  958.    TVwin_redraw(NIL) ;
  959.    TVfld_altmode(NIL,TRUE) ;
  960.    TVkbd_setflags(NIL,KBD_FILTERALL) ;
  961.    TVkbd_setesc(NIL,kbd_filter) ;
  962.    len = TVkbd_read(NIL,buffer,sizeof(buffer)) ;
  963.    status = (int) TVkbd_status(NIL) ;
  964.    TVfld_altmode(NIL,FALSE) ;
  965.    free(fields) ;  /* now we can finally free the stream */
  966.    TVwin_gotoxy(NIL,0,6) ;
  967.    TVwin_printf(NIL,"Got '%.*s'\r\nStatus was %d\r\nPress a key....",len,buffer,status) ;
  968.    get_key() ;
  969. }
  970.  
  971. /*===============================================================*/
  972. /*===============================================================*/
  973.  
  974. void open_window(void)
  975. {
  976.    OBJECT w ;
  977.    int row, col, rows, cols ;
  978.  
  979.    standard_window() ;
  980.    TVwin_title(NIL,"UIwin_open() test") ;
  981.    TVwin_swrite(NIL,"About to ask you to select a window's size and position" ) ;
  982.    TVwin_redraw(NIL) ;
  983.    TVsleep(100) ;
  984.    w = UIwin_open(NIL,2,2,25,70,5,20) ;
  985.    TVwin_clear(NIL) ;
  986.    TVwin_cursor(NIL,0,0) ;
  987.    if (w)
  988.       {
  989.       TVqry_position(w,&row,&col) ;
  990.       TVqry_size(w,&rows,&cols) ;
  991.       TVwin_cursor(w,0,0) ;
  992.       TVwin_printf(w,"New window's handle: %Fp\r\n", w) ;
  993.       TVwin_printf(w,"Size: %dx%d\r\nPosition: (%d,%d)\r\nPress a key...",rows,cols,row,col) ;
  994.       TVwin_top(w) ;
  995.       TVwin_redraw(w) ;
  996.       get_key() ;
  997.       TVwin_free(w) ;
  998.       }
  999.    else
  1000.       {
  1001.       TVwin_swrite(NIL,"Cancelled!  Press a key...") ;
  1002.       get_key() ;
  1003.       }
  1004. }
  1005.  
  1006. /*===============================================================*/
  1007. /* restore as much of the old state as we've been able to save   */
  1008. /*===============================================================*/
  1009.  
  1010. void restore_state(void)
  1011. {
  1012.    TVwin_lsize(NIL,orig_lrows,orig_lcols) ;
  1013.    TVwin_title(NIL,old_title) ;
  1014.    TVwin_frattr(NIL,old_frattr) ;
  1015.    TVwin_move(NIL,orig_row,orig_col) ;
  1016.    TVwin_resize(NIL,orig_rows,orig_cols) ;
  1017.    TVwin_origin(NIL,org_row,org_col) ;
  1018.    TVwin_redraw(NIL) ;  /* make sure screen is updated */
  1019. }
  1020.  
  1021. /*===============================================================*/
  1022.  
  1023. void do_all(void)
  1024. {
  1025.    stream_test() ;
  1026.    TVerrormsg(0,"TEST ERROR MESSAGE - press ESC",1,0,0,0);
  1027.    notify_test() ;
  1028.    timer_test() ;
  1029.    pointer_test();
  1030.    mouse_drawing_program() ;
  1031.    field_test() ;
  1032.    fork_test() ;
  1033.    interrupt_test() ;
  1034.    objectq_test() ;
  1035.    multiwindow_test() ;
  1036.    open_window() ;
  1037.    TVsound(200,5) ;
  1038.    TVsound(350,5) ;
  1039.    TVsound(500,5) ;
  1040.    TVsound(650,5) ;
  1041. }
  1042.  
  1043. /*===============================================================*/
  1044.  
  1045. MENU_ITEM main_menu_items[] = {
  1046.    { M_SPECIAL,"Do everything  \021─┘", '\r',0, FALSE },
  1047.    { M_SEP,    0,                       205, 0, FALSE },
  1048.    { M_HCENTER,"Single Tests",          0,   0, FALSE },
  1049.    { M_ITEM,   "Streams",               'S', 0, FALSE },
  1050.    { M_ITEM,   "Notification",          'N', 0, FALSE },
  1051.    { M_ITEM,   "Timers",                'T', 0, FALSE },
  1052.    { M_ITEM,   "Pointers...",           'P', 0, FALSE },
  1053.    { M_ITEM,   "Fields",                'F', 0, FALSE },
  1054.    { M_ITEM,   "Multitasking",          'M', 0, FALSE },
  1055.    { M_ITEM,   "Interrupts",            'I', 0, FALSE },
  1056.    { M_ITEM,   "objectQ",               'Q', 0, FALSE },
  1057.    { M_ITEM,   "Windows",               'W', 0, FALSE },
  1058.    { M_ITEM,   "Open window",           'O', 0, FALSE },
  1059.    { M_ITEM,   "soUnd...",              'U', 0, FALSE },
  1060.    { M_SEP,    0,                       205, 0, FALSE },
  1061.    { M_ITEM,   "eXit",                  'X', 0, FALSE },
  1062.    { M_END,    0,                       0,   0, FALSE }
  1063. } ;
  1064.  
  1065. MENU_OPTIONS main_menu_options = { " Demo ", 0, -1, FALSE, TRUE, TRUE, ' ' } ;
  1066.  
  1067. MENU_ITEM sound_menu_items[] = {
  1068.    { M_ITEM, "200 Hz tone",   '2', 0,   FALSE },
  1069.    { M_ITEM, "350 Hz tone",   '3', '5', FALSE },
  1070.    { M_ITEM, "500 Hz tone",   '5', 0,   FALSE },
  1071.    { M_ITEM, "650 Hz tone",   '6', '5', FALSE },
  1072.    { M_END,  0,               0,   0,   FALSE }
  1073. } ;
  1074.  
  1075. MENU_OPTIONS sound_menu_options = { " Sound Menu ", 16, -21, FALSE, TRUE, TRUE, ' ' } ;
  1076.  
  1077. MENU_ITEM pointer_menu_items[] = {
  1078.    { M_ITEM, "Program pointer movement", 'P', 0, FALSE },
  1079.    { M_ITEM, "Drawing program",          'D', 0, FALSE },
  1080.    { M_END,  0,                          0,   0, FALSE }
  1081. } ;
  1082.  
  1083. MENU_OPTIONS pointer_menu_options = { "Pointer Menu", 9, -21, FALSE, TRUE, TRUE, ' ' } ;
  1084.  
  1085. /*===============================================================*/
  1086.  
  1087. void sound_menu(void) ;
  1088. void pointer_menu(void) ;
  1089.  
  1090. void do_nothing(void)
  1091. {
  1092. }
  1093.  
  1094. void (*menu_functions[])(void) =
  1095.    {
  1096.    do_all, stream_test, notify_test, timer_test, do_nothing, field_test,
  1097.    fork_test, interrupt_test, objectq_test, multiwindow_test, open_window,
  1098.    do_nothing, do_nothing
  1099.    } ;
  1100.  
  1101. /*===============================================================*/
  1102.  
  1103. int menu_test(OBJECT window,int status,char *results)
  1104. {
  1105.    (void) window ;
  1106.    (void) results ;
  1107.    if (status == 2 || status == 27) /* right mouse button or ESC */
  1108.       return MA_REDO | MA_RESET ;
  1109.    else if (results[11] == 'Y')  /* is choice so'U'nd menu? */
  1110.       {
  1111.       sound_menu() ;
  1112.       results[11] = 'N' ;  /* reset the field */
  1113.       return MA_REDO | MA_SELECT ;
  1114.       }
  1115.    else if (results[4] == 'Y')   /* is choice 'P'ointer menu? */
  1116.       {
  1117.       pointer_menu() ;
  1118.       return MA_REDO | MA_RESET ;
  1119.       }
  1120.    else
  1121.       return MA_DONE ;
  1122. }
  1123.  
  1124. /*===============================================================*/
  1125.  
  1126. void sound_menu(void)
  1127. {
  1128.    void *menu = UImenu_build(sound_menu_items,&sound_menu_options) ;
  1129.    char results[5] ;  /* there are four items */
  1130.    int i ;
  1131.  
  1132.    if (menu == ME_TOOBIG)
  1133.       TVwin_printf(NIL, "Menu too big!\n") ;
  1134.    else if (menu == ME_NOMEM)
  1135.       TVwin_printf(NIL, "Not enough memory for menu!\n") ;
  1136.    else if (menu == ME_BADITEM)
  1137.       TVwin_printf(NIL, "Error in menu item!  You probably forgot the M_END\n" ) ;
  1138.    else
  1139.       {
  1140.       (void) UImenu_show(menu,TRUE,NULL,results) ;
  1141.       if (strchr(results,'Y') != NULL)
  1142.          TVsound(200+150*(strchr(results,'Y')-results),4) ;
  1143.       else /* hit Esc */
  1144.          {
  1145.          for (i = 0 ; i < 30 ; i++)
  1146.             TVsound(300+100*i,3) ;
  1147.          TVnosound() ;   /* test cancellation of enqueued notes */
  1148.          }
  1149.       }
  1150. }
  1151.  
  1152. /*===============================================================*/
  1153.  
  1154. void pointer_menu(void)
  1155. {
  1156.    void *menu = UImenu_build(pointer_menu_items,&pointer_menu_options) ;
  1157.    char results[3] ;
  1158.  
  1159.    if (menu == ME_TOOBIG)
  1160.       TVwin_printf(NIL, "Menu too big!\n") ;
  1161.    else if (menu == ME_NOMEM)
  1162.       TVwin_printf(NIL, "Not enough memory for menu!\n") ;
  1163.    else if (menu == ME_BADITEM)
  1164.       TVwin_printf(NIL, "Error in menu item!  You probably forgot the M_END\n" ) ;
  1165.    else
  1166.       {
  1167.       (void) UImenu_show(menu,TRUE,NULL,results) ;
  1168.       if (results[0] == 'Y')
  1169.          pointer_test() ;
  1170.       else if (results[1] == 'Y')
  1171.          mouse_drawing_program() ;
  1172.       }
  1173. }
  1174.  
  1175. /*===============================================================*/
  1176.  
  1177. void main_menu(void)
  1178. {
  1179.    void *menu = UImenu_build(main_menu_items,&main_menu_options) ;
  1180.    char results[14] ;  /* there are 13 menu items */
  1181.  
  1182.    if (menu == ME_TOOBIG)
  1183.       TVwin_printf(NIL, "Menu too big!\n" ) ;
  1184.    else if (menu == ME_NOMEM)
  1185.       TVwin_printf(NIL, "Not enough memory for menu!\n" ) ;
  1186.    else if (menu == ME_BADITEM)
  1187.       TVwin_printf(NIL, "Error in menu item!  You probably forgot the M_END\n" ) ;
  1188.    else
  1189.       {
  1190.       do {
  1191.          save_state() ;    /* save size/pos/title of window */
  1192.          (void) UImenu_show(menu,TRUE,menu_test,results) ;
  1193.          if (strchr(results,'Y') != NULL)
  1194.             (*menu_functions[strchr(results,'Y') - results])() ;
  1195.          restore_state() ; /* restore window to its previous state */
  1196.          } while (results[strlen(results)-1] == 'N') ;
  1197.       free( menu ) ;
  1198.       }
  1199. }
  1200.  
  1201. /*===============================================================*/
  1202.  
  1203. void main()
  1204. {
  1205.    /* initialize everything and return DESQview version number */
  1206.    if (DVinit() == 0)
  1207.       {
  1208.       fputs("This program requires DESQview 2.0 or later\n",stderr);
  1209.       exit(1);
  1210.       }
  1211.    main_menu() ;
  1212.    TVwin_clear(NIL) ;
  1213.    /* quit DESQview API */
  1214.    DVexit() ;
  1215. }
  1216.  
  1217. /* End of DEMO.C */
  1218.